package com.ruge.tool.json;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONValidator;
import com.alibaba.fastjson2.TypeReference;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.Map;

/**
 * json工具类
 *
 * @author ruge.wu
 * @since 2021-10-08 14:41
 **/
@Slf4j
public class JsonTool {
    /*====================================json2bean===========================================================*/

    /**
     * 功能描述：把JSON数据转换成指定的java对象
     *
     * @param jsonData JSON数据
     * @param clazz    指定的java对象
     * @param <T>      泛型
     * @return 指定的java对象
     */
    public static <T> T getJsonToBean(String jsonData, Class<T> clazz) {
        return JSON.parseObject(jsonData, clazz);
    }

    /**
     * 功能描述：把JSON数据转换成指定的java对象列表
     *
     * @param jsonData JSON数据
     * @param clazz    指定的java对象
     * @param <T>      泛型
     * @return 返回bean集合
     */
    public static <T> List<T> getJsonToBeans(String jsonData, Class<T> clazz) {
        return JSON.parseArray(jsonData, clazz);
    }

    /**
     * 功能描述：把JSON数据转换成较为复杂的map
     *
     * @param jsonData JSON数据
     * @return 返回map
     */
    public static Map<String, Object> getJsonToMap(String jsonData) {
        return JSON.parseObject(jsonData, new TypeReference<Map<String, Object>>() {
        });
    }

    /**
     * 功能描述：把JSON数据转换成较为复杂的map集合
     *
     * @param jsonData JSON数据
     * @return 返回map集合
     */
    public static List<Map<String, Object>> getJsonToMaps(String jsonData) {
        return JSON.parseObject(jsonData, new TypeReference<List<Map<String, Object>>>() {
        });
    }

    /**
     * 功能描述：把JSON数据转换成较为复杂的map
     *
     * @param jsonData JSON数据
     * @return 返回map
     */
    public static Map<String, String> getJsonToStringMap(String jsonData) {
        return JSON.parseObject(jsonData, new TypeReference<Map<String, String>>() {
        });
    }

    /*====================================obj2bean===========================================================*/

    /**
     * 对象转实体类
     *
     * @param obj   对象
     * @param clazz class
     * @param <T>   泛型
     * @return 返回对象
     */
    public static <T> T getObjToBean(Object obj, Class<T> clazz) {
        String beanToJson = getObjToJson(obj);
        return getJsonToBean(beanToJson, clazz);
    }

    /**
     * 对象转实体类
     *
     * @param obj   对象
     * @param clazz class
     * @param <T>   泛型
     * @return 返回对象集合
     */
    public static <T> List<T> getObjToBeans(Object obj, Class<T> clazz) {
        String beanToJson = getObjToJson(obj);
        return getJsonToBeans(beanToJson, clazz);
    }

    /**
     * 功能描述：把Object数据转换成较为复杂的map
     *
     * @param obj List数据
     * @return 返回map
     */
    public static Map<String, Object> getObjToMap(Object obj) {
        return JSON.parseObject(getObjToJson(obj), new TypeReference<Map<String, Object>>() {
        });
    }

    /**
     * 功能描述：把Object数据转换成较为复杂的map集合
     *
     * @param objData JSON数据
     * @return 返回map集合
     */
    public static List<Map<String, Object>> getObjToMaps(Object objData) {
        return JSON.parseObject(getObjToJson(objData), new TypeReference<List<Map<String, Object>>>() {
        });
    }

    /**
     * 功能描述：把Object数据转换成较为复杂的map
     *
     * @param obj List数据
     * @return 返回map
     */
    public static Map<String, String> getObjToStringMap(Object obj) {
        return JSON.parseObject(getObjToJson(obj), new TypeReference<Map<String, String>>() {
        });
    }


    /**
     * 功能描述：把java对象转换成JSON数据
     *
     * @param object java对象
     * @return 返回JSON数据
     */
    public static String getObjToJson(Object object) {
        return JSON.toJSONString(object);
    }

    /**
     * 功能描述：校验字符串是否是json
     *
     * @param json json字符串
     */
    public static void valid(String json) {
        System.out.println();
        System.out.println(JSONValidator.from(json).validate());
        if (!JSONValidator.from(json).validate()) {
            log.error("无效的json数据:{}", json);
            throw new RuntimeException("无效的json:" + json);
        }
    }

    /**
     * 是否能序列化
     *
     * @param obj {@link Object}
     * @return 是否是json
     */
    public static boolean isCanSerialize(Object obj) {
        String objToJson = JsonTool.getObjToJson(obj);
        return JSONValidator.from(objToJson).validate();
    }
}
